package com.py.payment.nettys.cilent;

import com.py.payment.nettys.msg.MyDecoder;
import com.py.payment.nettys.msg.MyEncoder;
import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.GenericFutureListener;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.nio.charset.Charset;
import java.util.Date;
import java.util.concurrent.TimeUnit;

@Slf4j
@Component
public class NettyClient {


    private String host = "111.52.239.19";

    private int port = 8018;

    private Channel channel;

    private Bootstrap bootstrap;

    private EventLoopGroup eventLoopGroup = new NioEventLoopGroup();

//    @PostConstruct
    public void connect(){
        doConnect();
    }


    public void writeAndFlush(Object msg){
        ByteBuf byteBuf = PooledByteBufAllocator.DEFAULT.buffer();
        byte[] bytes = msg.toString().getBytes(Charset.defaultCharset());
        byteBuf.writeBytes(bytes);
        this.channel.writeAndFlush(byteBuf)
                .addListener(new GenericFutureListener<Future<? super Void>>() {
            @Override
            public void operationComplete(Future<? super Void> future) throws Exception {
                if(future.isSuccess()){
                    log.info("消息发送成功");
                } else {
                    log.info("消息发送失败");
                }
            }
        });
    }

    private void doConnect(){
        bootstrap = new Bootstrap();
        bootstrap.group(eventLoopGroup);
        bootstrap.channel(NioSocketChannel.class);
//        bootstrap.option(ChannelOption.SO_KEEPALIVE, true);
        bootstrap.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
        bootstrap.remoteAddress(host,port);
        bootstrap.handler(new ChannelInitializer<SocketChannel>() {

            @Override
            protected void initChannel(SocketChannel ch) throws Exception {
                //编解码处理
//                ch.pipeline().addLast("decoder", new MyDecoder());
//                ch.pipeline().addLast("encoder", new MyEncoder());
                //异常处理
//                ch.pipeline().addLast("exception", exceptionHandler);
            }
        });
        log.info("开始连接服务端");
        ChannelFuture f = bootstrap.connect();
        f.addListener(connectedListener);
    }

    //连接关闭监听
    GenericFutureListener<ChannelFuture> closeListener = (ChannelFuture f) -> {
        log.info(new Date() + ": 连接已经断开……");
        channel = f.channel();
    };

    //连接监听
    GenericFutureListener<ChannelFuture> connectedListener = (ChannelFuture f) -> {
        final EventLoop eventLoop = f.channel().eventLoop();
        if (!f.isSuccess()) {
            log.info("连接失败!在10s之后准备尝试重连!");
            eventLoop.schedule(() -> doConnect(), 10, TimeUnit.SECONDS);
        } else {
            log.info("服务器 连接成功!" + f.channel().remoteAddress() + ":" + f.channel().localAddress());
            channel = f.channel();
        }
    };

}
